package com.suray.rgv60;

import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.utils.LoggerType;
import com.suray.basic.wcs.utils.ModuleType;
import com.suray.rgv.Rgv60Interface;
import com.suray.rgv.data.Rgv60InfoData;
import com.suray.rgv.util.ErrorInfo;
import com.suray.rgv.util.RgvLogger;
import com.suray.rgv60.core.Rgv60Core;
import com.suray.rgv60.generate.GeneralMapManage;
import com.suray.type.Rgv60PalletStatus;
import com.suray.type.Rgv60Status;
import com.suray.wcs.res.enums.Order;
import com.suray.wcs.res.enums.PalletStatus;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.res.enums.RgvType;

import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 两栖车实体，实现接口Rgv60Interface
 */
public class Rgv60Impl implements Rgv60Interface {
    /**
     * 6代车核心
     */
    private Rgv60Core rgv60Core;

    /**
     * 小车序列号
     */
    private String serialNum;

    /**
     * 小车ip
     */
    private String ip;

    public Rgv60Impl(int rgvNo, String serialNum, String ip) {
        this.serialNum = serialNum;
        this.rgv60Core = new Rgv60Core(rgvNo, serialNum, ModuleType.RGV_RES60);
        this.ip = ip;

        rgv60Core.start();

//        new Rgv60Test(this);
    }

    public void run() {
        try {
//            rgv60Core.run();
        } catch (Throwable e) {
            RgvLogger.exceptionLog(LoggerType.ERROR, null, serialNum + " 运行", e, this.getClass());
        }
    }

    @Override
    public void init() {
        try {
            rgv60Core.init(ip);
        } catch (Throwable e) {
            RgvLogger.exceptionLog(LoggerType.ERROR, null, serialNum + " 初始化", e, this.getClass());
        }
    }

    @Override
    public void initNet(String ip, int port) {
        try {
            rgv60Core.initNet(ip);
        } catch (Throwable e) {
            RgvLogger.exceptionLog(LoggerType.ERROR, null, serialNum + " 初始化网络", e, this.getClass());
        }
    }

    @Override
    public String getSeries() {
        return serialNum;
    }

    @Override
    public void generalTask(Integer taskId, List<Node> nodeList) {
        rgv60Core.generalTask(taskId, nodeList);
    }

    @Override
    public boolean task(Object taskId, List<Node> pathNodes) {
        return rgv60Core.task(taskId, pathNodes);
    }

    @Override
    public boolean isTaskEnd(int taskId) {
        return rgv60Core.isTaskEnd(taskId);
    }

    @Override
    public boolean isActionEnd(Order action) {
        return false;
    }

    @Override
    public Object getTaskId() {
        return rgv60Core.getTaskId();
    }

    @Override
    public int getTaskNo() {
        return 0;
    }

    @Override
    public boolean action(Order order) {
        try {
            return rgv60Core.action(order, null);
        } catch (IOException e) {
            throw new RuntimeException(order + "时, 执行失败, 通讯异常");
        }
    }

    @Override
    public boolean action(Order order, Object actionParam) {
        try {
            return rgv60Core.action(order, actionParam);
        } catch (IOException e) {
            throw new RuntimeException(order + "执行失败");
        }
    }

    @Override
    public boolean changeLocation(Node node) {
        //TODO MJ RGV60
        //只能行驶到某个点，暂不提供该功能
        return false;
    }

    @Override
    public ErrorInfo getErrorInfo() {
        return rgv60Core.getMaxError();
    }

    @Override
    public List<ErrorInfo> getErrorInfos() {
        return rgv60Core.getErrors();
    }

    @Override
    public void clearError(ErrorInfo error) {
        rgv60Core.removeError(error);
    }

    @Override
    public void clearAllError() throws IOException {
        rgv60Core.clearFault();
    }

    @Override
    public void clearTask() throws IOException {
        rgv60Core.clearTask();
    }

    @Override
    public boolean recovery() throws IOException {
        return rgv60Core.recovery();
    }

    @Override
    public Node getLocation() {
        return rgv60Core.getLocation();
    }

    @Override
    public RgvStatus getRgvStatus() {
        Rgv60Status rgv60Status = rgv60Core.getRgvStatus();

        switch (rgv60Status) {
            case RUNNING:
                return RgvStatus.RUNING;
            case STANDY:
                if (rgv60Core.hasTask()) {
                    return RgvStatus.NODE_STANDBY;
                }

                if (isCharging()) {
                    return RgvStatus.CHARGING;
                } else {
                    return RgvStatus.READY;
                }
            case ERROR:
                return RgvStatus.ERROR;
            case STOP:
                return RgvStatus.PAUSE;
            case NONE:
            case INIT:
                return RgvStatus.UNKNOWN;
            case OFF_LINE:
                return RgvStatus.OFF_LINE;
            case WAITING:
                return RgvStatus.NODE_STANDBY;
            default:
                break;
        }
        return null;
    }

    @Override
    public PalletStatus getRgvPalletStatus() {
        Rgv60PalletStatus rgv60PalletStatus =  rgv60Core.getPalletStatus();
        PalletStatus palletStatus;

        switch (rgv60PalletStatus) {
            case STOP:
            case FAIL:
                palletStatus = PalletStatus.ERROR;
                break;
            case DOWNING:
            case UP_OK:
                palletStatus = PalletStatus.UP;
                break;
            case UPING:
            case DOWN_OK:
                palletStatus = PalletStatus.DOWN;
                break;
            case INVALID:
            default:
                palletStatus = PalletStatus.UNKNOWN;
                break;
        }

        return palletStatus;
    }

    @Override
    public Float getBatSoc() {
        return rgv60Core.getBatSoc();
    }

    @Override
    public Float getBatTemp() {
        return rgv60Core.getBatTemp();
    }

    @Override
    public Float getBatVolt() {
        return rgv60Core.getBatVolt();
    }

    @Override
    public Float getBatCurrent() {
        return rgv60Core.getBatCur();
    }

    @Override
    public Integer getBatChargeNum() {
        return rgv60Core.getChargeNum();
    }

    @Override
    public Float getAutoChargeBattery() {
        return rgv60Core.getPermitChargeVolt();
    }

    @Override
    public Integer getForceChargeBattery() {
        return null;
    }

    @Override
    public boolean isForbidden() {
        return false;
    }

    @Override
    public boolean isAutoCharge() {
        return false;
    }

    @Override
    public boolean isRgvValid() {
        return true;
    }

    @Override
    public String getNetId() {
        return ip;
    }

    @Override
    public String getMap() {
        return rgv60Core.getMap();
    }

    @Override
    public int getRgvNo() {
        return 0;
    }

    @Override
    public boolean stopTask() {
        return false;
    }

    @Override
    public void cancelTask(int taskId) {

    }

    @Override
    public boolean emergencyStop() {
        return rgv60Core.emergencyStop();
    }

    @Override
    public RgvType getRgvType() {
        return RgvType.RGV_SIX_POINT_ZERO;
    }

    @Override
    public void sendMap(String wareHouse) throws IOException {
        List<File> files = GeneralMapManage.getMapFiles(wareHouse);
        rgv60Core.sendMap(files);
    }

    @Override
    public String downloadMap(String mapName) throws IOException {
        return rgv60Core.downloadMap(mapName);
    }

    public void deleteMap(String mapName) throws IOException {
        rgv60Core.deleteMap(mapName);
    }

    @Override
    public String getName() {
        return rgv60Core.getRobotName();
    }

    @Override
    public boolean isOnline() {
        return rgv60Core.isOnLine();
    }

    @Override
    public void setInterrupt() throws IOException {
        rgv60Core.setInterrupt();
    }

    @Override
    public void rgvError(ErrorInfo errorInfo) {
        rgv60Core.rgvError(errorInfo);
    }

    @Override
    public void forwardRun() {
        rgv60Core.forwardRun();
    }

    @Override
    public void fallBackRun() {
        rgv60Core.fallBackRun();
    }

    @Override
    public void turnLeft() {
        rgv60Core.turnLeft();
    }

    @Override
    public void turnRight() {
        rgv60Core.turnRight();
    }

    @Override
    public void stopManualMove() {
        rgv60Core.stopManualMove();
    }

    @Override
    public void changeMap(int layer) throws IOException {
        rgv60Core.changeMap(layer);
    }

    @Override
    public Integer getCurrentFloor() {
        return rgv60Core.getCurrentFloor();
    }

    @Override
    public void changeAuthor(boolean hasAuthor) throws IOException {
        rgv60Core.changeAuthor(hasAuthor);
    }

    @Override
    public boolean hasAuthor() {
        return rgv60Core.hasAuthor();
    }

    @Override
    public void resetPosition() throws IOException {
        rgv60Core.resetPosition();
    }

    @Override
    public boolean positionOk() {
        return rgv60Core.positionOk();
    }

    @Override
    public void destroy() {
        rgv60Core.endThread();
    }

    @Override
    public Rgv60InfoData getRgv60InfoData() {
        return rgv60Core.getRgv60InfoData();
    }

    public Boolean hasPallet() {
        return rgv60Core.hasPallet();
    }

    @Override
    public boolean isCharging() {
        return rgv60Core.isCharging();
    }

    @Override
    public boolean isStatic() {
        return rgv60Core.isStatic();
    }
}
